package com.example.demo;

import com.example.demo.config.TestConfig;
import com.example.demo.controller.TestController;
import com.example.demo.dao.TestDao;
import com.example.demo.model.Student;
import com.example.demo.service.TestService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

//@ComponentScan("com.example.demo")
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		// 接收Spring上下文，也就是IoC容器的实例对象
		ApplicationContext context = SpringApplication.run(DemoApplication.class, args);

		// 使用Spring上下文获取IoC中的 TestController对象
		// 获取成功！
		// System.out.println(testController);

		// 练习使用五大注解存储对象，并使用SpringContext进行取出
		System.out.println("----- next -----");
		// 1.@Controller注解
		TestController testController = context.getBean(TestController.class);
		testController.m1();
		// 2.@Service注解
		TestService testService = context.getBean(TestService.class);
		testService.m1();
		// 3.@Repository注解
		TestDao testDao = context.getBean("testDao", TestDao.class);
		testDao.m1();
		// 4.@Configuration注解
		// -- 若是使用名称进行获取，则需要对返回值进行强转，因为此时Spring并不知道返回值的类型
		TestConfig testConfig = (TestConfig)context.getBean("testConfig");
		testConfig.m1();
		// 5.@Component注解
		// -- 我感觉像是实体类，就可以使用@Component注解进行存储bean，但是我又感觉是@Repository
		//		Student student = context.getBean(Student.class);
		//		student.m1();
		System.out.println("---- hr ----");

		// 尝试一个类取多次对象，看对象是否为一个
		TestConfig bean1 = context.getBean(TestConfig.class);
		TestConfig bean2 = context.getBean(TestConfig.class);
		TestConfig bean3 = context.getBean(TestConfig.class);
		System.out.println(bean1);
		System.out.println(bean2);
		System.out.println(bean3);
		System.out.println("---- hr ----");

		// @Bean方法注解使用示例
		// 1.@Bean方法注解必须结合五大注解进行使用才会生效
		// 2.使用@Bean方法可以存储相同类型的对象进Spring IoC容器中
		//		Student studentOne = context.getBean("studentOne", Student.class);
		//		System.out.println(studentOne);
		//
		//		Student studentTwo = context.getBean("studentTwo", Student.class);
		//		System.out.println(studentTwo);

		// 获取由@Bean方法注解所存储的对象
		// -- 1，直接通过类型进行获取，由于该类型存在两个相同的对象，因此报错
		// Student student = context.getBean(Student.class);
		// System.out.println(student);
		// -- 2，使用类型 + 对象名称进行获取
		//		Student studentOne = context.getBean("studentOne", Student.class);
		//		Student studentTwo = context.getBean("studentTwo", Student.class);
		//		System.out.println("One:\n" + "  " + studentOne.toString());
		//		System.out.println("Two:\n" + "  " + studentTwo.toString());

		// @Bean对象重命名操作
		// -- 通过@Bean(name = {"", ""}) 修改name属性的方式，可以对存储的bean进行重命名，且可以命名多个
		// -- 但是需要注意的是，一个bean可以对应多个名称，但是一个名称只能对应一个bean
		Student student1 = context.getBean("s1", Student.class);
		Student student2 = context.getBean("ss", Student.class);
		System.out.println(student1);
		System.out.println(student1);
	}

}
